package com.lindenvalley.ch.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

import android.util.Log;

import com.lindenvalley.ch.content.Task;
import com.lindenvalley.ch.content.User;
import com.lindenvalley.ch.content.Weeks;
import com.lindenvalley.ch.parser.UserXmlParser;

public class WorkServer{
	
	private DefaultHttpClient httpClient;
	private HttpGet requestGet;	
	private HttpPost requestPost;
	private HttpResponse response;
	private static final String HOST = "http://www.berichtsheftapp.info/";
	private static final String LOGIN_SCRIPT = "wp-mlogin.php?";
	private static final String GET_TASKS_SCRIPT = "wp-get-tasks_new.php?";
	private static final String GET_TASKS_PERIOD_SCRIPT = "wp-get-periods.php?";
	private static final String CHANGE_AUSBILD_NUMBER = "wp-set-label.php?";
	private static final String CHANGE_AUSBILD_NUMBER_PERIOD = "wp-set-labels.php?";
	private static final String POST_TASKS_SCRIPT = "wp-tasks.php";
	private static final String API_PATH = "api/";
	private static final String PDF_SCRIPT = "pdf/pdfuploaer.php";
	private static final String INIT_SCRIPT = "start.php";
	public static final String NOT_CONNECT = "notconnect";
	public static final String TASK_ADD = "add";
	public static final String TASK_UPDATE = "update";
	public static final String TASK_DELETE = "del";
	private StringBuffer sb;
	private URI uri;
	private static WorkServer instance;
	private final String TAG = getClass().getSimpleName();
	public static final String SUCCESS_VALUE = "success";
	public static final String DENY_VALUE = "denay";
	public static final String ERROR_VALUE = "error";
	private UserXmlParser userParser;
	private CookieStore cookieStore;
    // Create local HTTP context
    private HttpContext localContext;
    private User user;
    private Weeks weeks;
    private Weeks notSynchWeeks;
    private boolean needConnect;
	
	
	
	private WorkServer() {
		super();
		sb = new StringBuffer("");
		initHttpClient();
		needConnect = true;
	}
	
	public static WorkServer getInstance(){
		if (instance == null){
			synchronized (WorkServer.class){
				if (instance == null){
					instance = new WorkServer();
				}
			}
		}
		return instance;
	}


	public Object doLogin(String userName, String password){		
		Object result = DENY_VALUE;
		User user = null;
		if (userName != null && password != null){
			try{
				uri = URI.create(HOST + API_PATH + LOGIN_SCRIPT + "u=" + userName + "&p=" + password);
				requestGet = new HttpGet(uri);
				result = doRequest(requestGet);				
				if (result != null && ((String)result).length() > 0 && !DENY_VALUE.equals(result)){
					userParser = new UserXmlParser((String)result);
					user = userParser.parse();
					if (user != null)
						result = user;					
				} else {
					result = DENY_VALUE;
				}
				
			} catch (IllegalArgumentException ex){
				ex.printStackTrace();
			}
						
		} 
		return result;
	}
	
	public String getTasksOld(int userId, String date, String sessionId){
		
		String result = null;
		try{
			uri = URI.create(HOST + API_PATH + GET_TASKS_SCRIPT + "id="+ userId + "&sid=" + sessionId);
			requestGet = new HttpGet(uri);
			result = doRequest(requestGet);
		} catch (IllegalArgumentException ex){
			ex.printStackTrace();
		}
		
		return result;
		
	}
	
	public String getTasks(int userId, int year){
		
		String result = null;
		try{
			uri = URI.create(HOST + API_PATH + GET_TASKS_SCRIPT + "id="+ userId + "&year=" + year);
			requestGet = new HttpGet(uri);
			result = doRequest(requestGet);
		} catch (IllegalArgumentException ex){
			ex.printStackTrace();
		}
		
		return result;
		
	}
	
	public String getWeekPeriod(int fromYear, int toYear){
		
		String result = null;
		try{
			uri = URI.create(HOST + API_PATH + GET_TASKS_PERIOD_SCRIPT + "user_id="+ user.getUserId() + "&year1=" + fromYear + "&year2=" + toYear);
			requestGet = new HttpGet(uri);
			result = doRequest(requestGet);
		} catch (IllegalArgumentException ex){
			ex.printStackTrace();
		}
		
		return result;
		
	}
	
	
	public String doTask(String action, Task task, User user){
		
		String result = null;
		if (task == null || user == null)
			return result;
		
		requestPost = new HttpPost(HOST + API_PATH + POST_TASKS_SCRIPT);
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
	    nameValuePairs.add(new BasicNameValuePair("action", action));
//	    nameValuePairs.add(new BasicNameValuePair("sid", user.getSessionId()));
	    nameValuePairs.add(new BasicNameValuePair("user_id", user.getUserId()+""));
	    if (TASK_UPDATE.equals(action) || TASK_ADD.equals(action)){
		    String value = task.getTaskText();
		    if (value != null)
		    	nameValuePairs.add(new BasicNameValuePair("tatigkeit", value));
		    else
		    	nameValuePairs.add(new BasicNameValuePair("tatigkeit", ""));
		    value = task.getBerufssText();
		    if (value != null)
		    	nameValuePairs.add(new BasicNameValuePair("berufss", value));
		    else
		    	nameValuePairs.add(new BasicNameValuePair("berufss", ""));
		    value = task.getThemenText();
		    if (value != null)
		    	nameValuePairs.add(new BasicNameValuePair("themen", value));
		    else
		    	nameValuePairs.add(new BasicNameValuePair("themen", ""));
		    value = task.getTaskTime();
		    if (value != null)
		    	nameValuePairs.add(new BasicNameValuePair("einzelstunden", value));
		    else
		    	nameValuePairs.add(new BasicNameValuePair("einzelstunden", ""));
		    value = task.getPlace();
		    if (value != null)
		    	nameValuePairs.add(new BasicNameValuePair("place", value));
		    else
		    	nameValuePairs.add(new BasicNameValuePair("place", ""));
		    value = task.getTaskTime();
		    if (value != null)
		    	nameValuePairs.add(new BasicNameValuePair("time", value));
		    else
		    	nameValuePairs.add(new BasicNameValuePair("time", ""));
		    
		    value = String.valueOf(task.getDate());
		    nameValuePairs.add(new BasicNameValuePair("date_task", value));
	    }
	    
	    
	    if (TASK_UPDATE.equals(action) || TASK_DELETE.equals(action))
	    	nameValuePairs.add(new BasicNameValuePair("task_id", task.getTaskId()+""));
						
		try{
			requestPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			result = doRequest(requestPost);
		} catch (IllegalArgumentException ex){
			ex.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
		
	}

	/**
	 * Change Ausbild number for week
	 * @param startDate
	 * @param number
	 * @return
	 */
	public String changeAusbildNumber(long startDate, String number){
		String result = null;
		requestGet = new HttpGet(HOST + API_PATH + CHANGE_AUSBILD_NUMBER + 
				"user_id=" + user.getUserId() + 
				"&start_week=" + startDate + 
				"&label=" + number + 
				"&session=" + user.getSessionId());
		result = doRequest(requestGet);
		
		return result;
	}
	
	/**
	 * Change Ausbild number for period
	 * @param startDate
	 * @param number
	 * @return
	 */
	public String changeAusbildNumberPeriod(long startDate, long endDate, String number){
		String result = null;
		requestGet = new HttpGet(HOST + API_PATH + CHANGE_AUSBILD_NUMBER_PERIOD + 
				"user_id=" + user.getUserId() + 
				"&start_week=" + startDate +
				"&end_week=" + endDate +
				"&start_number=" + number + 
				"&session=" + user.getSessionId());
		result = doRequest(requestGet);
		
		return result;
	}
	
	public String setupFirstWeek(User user, String date){
		String result = null;
		if (date == null || user == null)
			return result;
		
		requestPost = new HttpPost(HOST + POST_TASKS_SCRIPT);
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
	    nameValuePairs.add(new BasicNameValuePair("action", "start_up"));
	    nameValuePairs.add(new BasicNameValuePair("start_up", date));
	    nameValuePairs.add(new BasicNameValuePair("user_id", user.getUserId()+""));
	    
	    try{
			requestPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			result = doRequest(requestPost);
		} catch (IllegalArgumentException ex){
			ex.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
		
	}
	
	/**
	 * Send PDF report to teacher
	 * pdfuploaer.php?week_start=1329091200&azubi=7
	 * @param weekNumder
	 * @param year
	 * @param mail
	 * @param subject
	 * @param body
	 * @return
	 */
	public String sendReport(String weekNumder, String year, String mail, String subject, String body){
		String result = "";
		requestPost = new HttpPost(HOST + PDF_SCRIPT);
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
		nameValuePairs.add(new BasicNameValuePair("id", user.getUserId()+""));
		nameValuePairs.add(new BasicNameValuePair("wk", weekNumder));
	    nameValuePairs.add(new BasicNameValuePair("year", year));
	    nameValuePairs.add(new BasicNameValuePair("mails", mail));
	    nameValuePairs.add(new BasicNameValuePair("title_mesg", subject));
	    nameValuePairs.add(new BasicNameValuePair("text_msg", body));
	    try{
			requestPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			result = doRequest(requestPost);
		} catch (IllegalArgumentException ex){
			ex.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	    
	}
	
	public void destroy(){		
		instance = null;
	}
	
	private void initSession(){		
		uri = URI.create(HOST + INIT_SCRIPT);
		requestGet = new HttpGet(uri);		
		cookieStore = new BasicCookieStore();

	    // Create local HTTP context
	    localContext = new BasicHttpContext();
	    // Bind custom cookie store to the local context
	    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

		String result = doRequest(requestGet);
//		if (result != null && result.length() > 0 && !NOT_CONNECT.equals(result))
//			isSendCoockie = true;
	}
	
	private void initHttpClient(){
		if (needConnect){
			httpClient = new DefaultHttpClient();
			needConnect = false;
		}
	}
	
	private synchronized String doRequest(HttpUriRequest uriRequest){
		String result = null;
		try {
			Log.i(TAG, "URL request: " + uriRequest.getURI());
			if (needConnect)
				initHttpClient();
			response = httpClient.execute(uriRequest, localContext);
			BufferedReader in = new BufferedReader
            (new InputStreamReader(response.getEntity().getContent()));	            
            String line = "";
            sb.setLength(0);
            sb.trimToSize();
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
//            	sb.append(line);
            }
            in.close();
            result = sb.toString();
			
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			result = NOT_CONNECT;
			needConnect = true;
		}
		return result;
	}
	
	public void clearData(){
		user = null;
		weeks = null;
	}

	/**
	 * @param user the user to set
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * @return the user
	 */
	public User getUser() {
		return user;
	}

	/**
	 * @param weeks the weeks to set
	 */
	public void setWeeks(Weeks weeks) {
		this.weeks = weeks;
	}

	/**
	 * @return the weeks
	 */
	public Weeks getWeeks() {
		return weeks;
	}

	public void setNotSynchWeeks(Weeks notSynchWeeks) {
		this.notSynchWeeks = notSynchWeeks;
	}

	public Weeks getNotSynchWeeks() {
		return notSynchWeeks;
	}
	
	
	

}
